extends IBasicComponent


class_name HttpResourceLoader
"""
基于Http的资源加载器
"""


## HTTP对象
@export var http_request: HTTPRequest = null
## 添加任务时是否立即下载
@export var is_download_immediately: bool = true


class DownloadTask:
    var url: String
    var on_success: Callable
    var on_failed: Callable

    func make(download_url: String, on_download_success: Callable, on_download_failed: Callable) -> DownloadTask:
        url = download_url
        on_success = on_download_success
        on_failed = on_download_failed
        return self


# 下载队列
var download_queue: Array[DownloadTask] = []


func __check_exports() -> Dictionary:
    return IComponent.merge({
        "http_request": IComponent.find_down.bind(self, func(x): return x is HTTPRequest, http_request),
    }, super.__check_exports())

func __init_hooks() -> Dictionary:
    return IComponent.merge({
        http_request.request_completed: __on_http_request_completed,
    }, super.__init_hooks())

func __on_http_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) -> void:
    var task = __download_done()
    if result != HTTPRequest.RESULT_SUCCESS:
        task.on_failed.call()
        return
    task.on_success.call(body)

func __download_done() -> DownloadTask:
    var task = download_queue[0]
    download_queue.remove_at(0)
    if download_queue.size() > 0:
        __download_start(download_queue[0])
    return task

func __download_start(task: DownloadTask) -> void:
    var err = http_request.request(task.url)
    if err != OK:
        task.on_failed.call()
        __download_done()

func start() -> void:
    # 当前任务为第一个任务
    if download_queue.size() < 2:
        __download_start(download_queue[0])

func download(url: String, on_download_success: Callable) -> void:
    var task = DownloadTask.new().make(url, on_download_success, func(): push_warning("download failed."))
    download_queue.push_back(task)

    if is_download_immediately:
        start()
